Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

EIP-2046 independent activation #5741

Merged
merged 7 commits into from
Nov 6, 2019
Merged

EIP-2046 independent activation #5741

merged 7 commits into from
Nov 6, 2019

Conversation

gumb0
Copy link
Member

@gumb0 gumb0 commented Sep 10, 2019

Addresses #5789

It introduces support for individual EIP activation without fork, then moves EIP-2046 implementation from Berlin fork definition to this new individual model of activation.

How this is supposed to be used

Implementing new EIP

Including EIP into the new fork definition, after it's accepted

Writing a unit test

Writing consensus state test

  • Use Forkname+EIPXXXX instead of regular fork name.
    See example test for EIP2046 that I created ethereum/tests@8bbbd48
    (based on existing CallIdentitiy_1 test)

Limitations / future improvements (if needed)

  • Not supported in blockchain tests, transaction tests
  • Not supported in generating blockchain tests from state tests
  • Not supported in chain config json, only in testeth. So it's not possible to create a chain with individual EIPs activated, that also means it won't work for retesteth.

These should be fairly easy to support though.

@winsvega please review the changes in testeth. Basically it operates now with a network name string (which can possibly contain additional EIP numbers) in the places where it used to use eth::Network. Then creates ChainParams based on this string, when it needs to execute the transaction.

@gumb0 gumb0 changed the title EIP-2046 separate activation EIP-2046 independent activation Sep 25, 2019
@gumb0 gumb0 force-pushed the eip-2046-separate branch 2 times, most recently from 9945c5d to 0413a31 Compare October 24, 2019 13:39
@codecov-io
Copy link

codecov-io commented Oct 24, 2019

Codecov Report

❗ No coverage uploaded for pull request base (master@57b8156). Click here to learn what that means.
The diff coverage is 79.34%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #5741   +/-   ##
=========================================
  Coverage          ?   64.08%           
=========================================
  Files             ?      360           
  Lines             ?    30830           
  Branches          ?     3425           
=========================================
  Hits              ?    19756           
  Misses            ?     9844           
  Partials          ?     1230

@gumb0
Copy link
Member Author

gumb0 commented Oct 30, 2019

Rebased.

@halfalicious
Copy link
Contributor

You mentioned in the issue that the syntax for specifying at runtime which EIPs to enable is a delimited list of EIPs - is there a chance that different EIPs can change the same settings so the ordering of the EIPs in the list matters? Or is this generally not a concern?

@halfalicious
Copy link
Contributor

What happens if someone specifies an eip not in the "AdditionalEIPs" struct? Presumably we get some sort of error?

@@ -147,6 +180,18 @@ ChainParams ChainParams::loadGenesis(string const& _json, h256 const& _stateRoot
return cp;
}

ChainParams ChainParams::addEIPs(AdditionalEIPs const& _eips) const
{
ChainParams cp(*this);
Copy link
Contributor

@halfalicious halfalicious Nov 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{*this}?

@@ -51,6 +59,9 @@ struct ChainParams: public ChainOperationParams
ChainParams loadConfig(std::string const& _json, h256 const& _stateRoot = {},
const boost::filesystem::path& _configPath = {}) const;

/// Activatie additional EIPs on top of the last fork block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo (Activatie -> Activate)

{
// network name may be network+EIPs
vector<string> networkAndEIPs;
boost::algorithm::split(networkAndEIPs, _networkName, boost::is_any_of("+"));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no appropriate STL function that we can use?

Copy link
Member Author

@gumb0 gumb0 Nov 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, string functions are pretty low-level and/or verbose (like you could of course string::find in a loop)

I like boost string functions because they create higher-level code, e.g. similar to split/join functions of other languages.

(We're probably going to get split via ranges in C++20 https://stackoverflow.com/questions/48402558/how-to-split-a-stdstring-into-a-range-v3-of-stdstring-views)

@@ -855,11 +896,11 @@ void ImportTest::traceStateDiff()

for(auto const& tr : m_transactions)
{
if (network == netIdToString(tr.netId) || network == "ALL")
if (network == tr.netId || network == "ALL")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Nit) Perhaps we should make this comparison case-insensitive?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's case-sensitive everywhere in testeth, I'd leave it like this.

(these strings are actually field names test JSON files, so proper behaviour depends on whether field names are case-sensitive in JSON, are they?)

Copy link
Contributor

@halfalicious halfalicious Nov 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, if it's already case sensitive everywhere else let's leave it alone.

@@ -37,6 +59,12 @@ ChainParams::ChainParams(string const& _json, h256 const& _stateRoot)
*this = loadConfig(_json, _stateRoot);
}

ChainParams::ChainParams(std::string const& _s, AdditionalEIPs const& _additionalEIPs)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Nit) Can we choose a name for the _s arg which reflects the semantics of the data it contains?

ChainParams::ChainParams(std::string const& _s, AdditionalEIPs const& _additionalEIPs)
: ChainParams(_s)
{
*this = addEIPs(_additionalEIPs);
Copy link
Contributor

@halfalicious halfalicious Nov 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this approach is a little confusing (calling another ctor which sets some state and then overwriting the current instance) - I'd prefer if the addEIPs function either updates the current instances state (i.e. it's non-const) or we turn this ctor into a static function which calls addEIPs and returns the result.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this is complicated. I originally added only addEIPs and made it similar to loadConfig and loadGenesis (which create new instance out of the current one)

But now I think I should remove addEIPs and leave only this constructor.

@gumb0
Copy link
Member Author

gumb0 commented Nov 4, 2019

You mentioned in the issue that the syntax for specifying at runtime which EIPs to enable is a delimited list of EIPs - is there a chance that different EIPs can change the same settings so the ordering of the EIPs in the list matters? Or is this generally not a concern?

@halfalicious In theory it's possible, even if not about the same settings, some rules might be interrelated so that the order of applying matters... But I think the complexity of handling such flexibility is not worth the trouble for now (that is, EIPs in close areas will be applied in hard-coded order)

What happens if someone specifies an eip not in the "AdditionalEIPs" struct? Presumably we get some sort of error?

Not sure if I understand the question, but if someone implements an EIP, there will be some kind of check against chainParams to activate it - like without this individual activation the check looked like if (blockNumber >= chainParams.EIP158ForkBlock) - and this way EIP is included in some fork definition.

ChainParams::ChainParams(std::string const& _configJson, AdditionalEIPs const& _additionalEIPs)
: ChainParams(_configJson)
{
lastForkAdditionalEIPs = _additionalEIPs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Nit) Can we initialize this as a part of the initializers list?

@@ -19,6 +19,8 @@ struct EVMSchedule
{
EVMSchedule(): tierStepGas(std::array<unsigned, 8>{{0, 2, 3, 5, 8, 10, 20, 0}}) {}
EVMSchedule(bool _efcd, bool _hdc, unsigned const& _txCreateGas): exceptionalFailedCodeDeposit(_efcd), haveDelegateCall(_hdc), tierStepGas(std::array<unsigned, 8>{{0, 2, 3, 5, 8, 10, 20, 0}}), txCreateGas(_txCreateGas) {}
// consturct schedule with additional EIPs on top
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Nit) Spelling typo

@halfalicious halfalicious self-requested a review November 5, 2019 05:01
Copy link
Contributor

@halfalicious halfalicious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor suggestions, otherwise looks good!

@gumb0
Copy link
Member Author

gumb0 commented Nov 5, 2019

@winsvega @chfast I'm going to merge this today, if no reviews from you

@gumb0 gumb0 merged commit c936c07 into master Nov 6, 2019
@gumb0 gumb0 deleted the eip-2046-separate branch November 6, 2019 10:53
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants